package com.sendtion.xrichtextdemo.slice;

import static com.zhihu.matisse.MatisseAbility.RESULT_OK;

import com.sendtion.xrichtext.RichTextEditor;
import com.sendtion.xrichtextdemo.ResourceTable;
import com.sendtion.xrichtextdemo.bean.Group;
import com.sendtion.xrichtextdemo.bean.Note;
import com.sendtion.xrichtextdemo.db.GroupDao;
import com.sendtion.xrichtextdemo.db.NoteDao;
import com.sendtion.xrichtextdemo.utils.*;

import com.zhihu.matisse.Matisse;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.utils.TextUtils;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.components.TextField;
import ohos.agp.window.dialog.ToastDialog;
import ohos.agp.window.service.WindowManager;
import ohos.app.Environment;
import ohos.bundle.AbilityInfo;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.utils.net.Uri;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * NewAbilitySlice
 *
 * @since 2021-06-22
 */
public class NewAbilitySlice extends AbilitySlice implements Component.ClickedListener {
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "NewAbilitySlice");
    private static final int CUTITLELENGTH = 20;
    private static final int TITLE_COLOR = -13615201;
    private static final int REQUEST_CODE_CHOOSE = 23;
    private static final int INT_3 = 3;
    private static final int INT_360 = 360;
    private static final float FLOAT = 0.85f;
    private TextField etnewtitle;
    private Text actionnewsave;
    private Text actioninsertimage;
    private Text tvnewtime;
    private Text tvnewgroup;
    private Text titlename;
    private DirectionalLayout back;
    private GroupDao groupDao;
    private NoteDao noteDao;
    private Note note;
    private String myGroupName;
    private int flag;
    private String myTitle;
    private String myContent;
    private String myNoteTime;
    private String oldName;
    private ToastDialog loadingDialog;
    private ToastDialog insertDialog;
    private RichTextEditor etnewcontent;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_new);
        WindowManager.getInstance().getTopWindow().get().setStatusBarColor(TITLE_COLOR);
        initView(intent);
    }

    private void initView(Intent intent) {
        back = (DirectionalLayout) findComponentById(ResourceTable.Id_back);
        actionnewsave = (Text) findComponentById(ResourceTable.Id_action_new_save);
        actioninsertimage = (Text) findComponentById(ResourceTable.Id_action_insert_image);
        etnewtitle = (TextField) findComponentById(ResourceTable.Id_et_new_title);
        tvnewtime = (Text) findComponentById(ResourceTable.Id_tv_new_time);
        tvnewgroup = (Text) findComponentById(ResourceTable.Id_tv_new_group);
        titlename = (Text) findComponentById(ResourceTable.Id_title_name);
        etnewcontent = (RichTextEditor) findComponentById(ResourceTable.Id_et_new_content);

        groupDao = new GroupDao(this);
        noteDao = new NoteDao(this);
        note = new Note();
        etnewtitle.requestFocus();
        back.setClickedListener(this);
        actionnewsave.setClickedListener(this);
        actioninsertimage.setClickedListener(this);
        flag = intent.getIntParam("flag", 0);
        if (flag == 1) {
            titlename.setText("编辑笔记");
            note = intent.getSerializableParam("note");

            if (note != null) {
                myTitle = note.getTitle();
                myContent = note.getContent();
                myNoteTime = note.getCreateTime();
                oldName = note.getFileName();
                Group group = groupDao.queryGroupById(note.getGroupId());
                if (group != null) {
                    myGroupName = group.getName();
                    tvnewgroup.setText(myGroupName);
                }

                loadingDialog = new ToastDialog(this);
                loadingDialog.setText("数据加载中...");
                loadingDialog.setSwipeToDismiss(false);
                loadingDialog.show();

                tvnewtime.setText(note.getCreateTime());
                etnewtitle.setText(note.getTitle());

                dealWithContent();
            }
        } else {
            titlename.setText("新建笔记");
            if (myGroupName == null || "全部笔记".equals(myGroupName)) {
                myGroupName = "默认笔记";
            }
            tvnewgroup.setText(myGroupName);
            myNoteTime = CommonUtil.date2string(new Date());
            tvnewtime.setText(myNoteTime);
        }
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_back:
                if (flag == 1) {
                    saveNoteData(false);
                }
                onBackPressed();
                break;
            case ResourceTable.Id_action_insert_image:
                callGallery();
                break;
            case ResourceTable.Id_action_new_save:
                saveNoteData(false);
                break;
            default:
                break;
        }
    }

    private void dealWithContent() {
        etnewcontent.clearAllLayout();
        showDataSync(note.getContent());

        etnewcontent.setOnRtImageDeleteListener(new RichTextEditor.OnRtImageDeleteListener() {
            @Override
            public void onRtImageDelete(String imagePath) {
                if (!TextUtils.isEmpty(imagePath)) {
                    boolean isOk = SDCardUtil.deleteFile(imagePath);
                    if (isOk) {
                        MyToast.show(getContext(), "删除成功：" + imagePath, MyToast.ToastLayout.BOTTOM);
                    }
                }
            }
        });
        etnewcontent.setOnRtImageClickListener(new RichTextEditor.OnRtImageClickListener() {
            @Override
            public void onRtImageClick(Component view, String imagePath) {
                myContent = getEditData();
                if (!TextUtils.isEmpty(myContent)) {
                    List<String> imageList = StringUtils.getTextFromHtml(myContent, true);
                    if (!TextUtils.isEmpty(imagePath)) {
                        int currentPosition = imageList.indexOf(imagePath);
                        MyToast.show(getContext(), "点击图片：" + currentPosition + "：" + imagePath,
                                MyToast.ToastLayout.BOTTOM);
                        ArrayList<Uri> dataList = new ArrayList<>();
                        for (int i = 0; i < imageList.size(); i++) {
                            dataList.add(getUriFromPath(imageList.get(i)));
                        }
                        DialogUtil.show(getContext(), dataList, currentPosition);
                    }
                }
            }
        });
    }

    private Uri getUriFromPath(String imagePath) {
        Uri uri = null;
        if (!imagePath.isEmpty()) {
            if (imagePath.startsWith("http")) {
                uri = Uri.parse(imagePath);
            } else {
                File file = new File(imagePath);
                if (file.exists()) {
                    uri = Uri.getUriFromFile(file);
                }
            }
        }
        return uri;
    }

    private void showDataSync(String html) {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) {
                showEditData(emitter, html);
            }
        })
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onComplete() {
                        if (loadingDialog != null) {
                            loadingDialog.remove();
                        }
                        if (etnewcontent != null) {
                            etnewcontent.addEditTextAtIndex(etnewcontent.getLastIndex(), "");
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        if (loadingDialog != null) {
                            loadingDialog.remove();
                        }
                        showToast("解析错误：图片不存在或已损坏");
                    }

                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(String text) {
                        if (etnewcontent != null) {
                            if (text.contains("<img") && text.contains("src=")) {
                                String imagePath = StringUtils.getImgSrc(text);
                                etnewcontent.addEditTextAtIndex(etnewcontent.getLastIndex(), "");
                                etnewcontent.addImageViewAtIndex(etnewcontent.getLastIndex(), imagePath);
                            } else {
                                etnewcontent.addEditTextAtIndex(etnewcontent.getLastIndex(), text);
                            }
                        }
                    }
                });
    }

    /**
     * 显示数据
     *
     * @param emitter
     * @param html
     */
    protected void showEditData(ObservableEmitter<String> emitter, String html) {
        List<String> textList = StringUtils.cutStringByImgTag(html);
        for (int i = 0; i < textList.size(); i++) {
            String text = textList.get(i);
            emitter.onNext(text);
        }
        emitter.onComplete();
    }

    /**
     * 负责处理编辑数据提交等事宜，请自行实现
     *
     * @return String
     */
    private String getEditData() {
        StringBuilder content = new StringBuilder();
        List<RichTextEditor.EditData> editList = etnewcontent.buildEditData();
        for (RichTextEditor.EditData itemData : editList) {
            if (itemData.inputStr != null) {
                content.append(itemData.inputStr);
            } else if (itemData.imagePath != null) {
                content.append("<img src=\"").append(itemData.imagePath).append("\"/>");
            }
        }
        return content.toString();
    }

    /**
     * 保存
     *
     * @param isBackground
     */
    private void saveNoteData(boolean isBackground) {
        String noteTitle = etnewtitle.getText();
        String noteContent = getEditData();
        String groupName = tvnewgroup.getText();
        String noteTime = tvnewtime.getText();

        if (flag == 0) {
            if (noteTitle.length() == 0 && noteContent.length() == 0) {
                if (!isBackground) {
                    MyToast.show(getContext(), "请输入内容", MyToast.ToastLayout.BOTTOM);
                }
            } else {
                if (noteTitle.length() == 0) {
                    if (noteContent.length() > CUTITLELENGTH) {
                        noteTitle = noteContent.substring(0, CUTITLELENGTH);
                    } else if (noteContent.length() > 0) {
                        noteTitle = noteContent;
                    }
                }
                SaveDrawingTask.name = noteTime + ":" + System.currentTimeMillis() + ":" + noteTitle;
                saveFile(noteContent);
                flag = 1;
                if (!isBackground) {
                    onBackPressed();
                }
            }
        } else if (flag == 1) {
            if (!noteTitle.equals(myTitle) || !noteContent.equals(myContent)
                    || !groupName.equals(myGroupName) || !noteTime.equals(myNoteTime)) {
                if (noteTitle.length() == 0) {
                    if (noteContent.length() > CUTITLELENGTH) {
                        noteTitle = noteContent.substring(0, CUTITLELENGTH);
                    } else if (noteContent.length() > 0) {
                        noteTitle = noteContent;
                    }
                }
                renameFile(noteTitle);
            }
            if (!isBackground) {
                onBackPressed();
            }
        }
    }

    private void saveFile(String value) {
        SaveDrawingTask saveDrawingTask = new SaveDrawingTask(this);
        saveDrawingTask.setValue(value);
        new Thread(saveDrawingTask).start();
    }

    private void renameFile(String newName) {
        File oldFile = new File(this.getApplicationContext().getExternalFilesDir(
                Environment.DIRECTORY_DOCUMENTS), oldName);
        boolean isExists = oldFile.exists();
        if (isExists) {
            File newFile = new File(this.getApplicationContext().getExternalFilesDir(
                    Environment.DIRECTORY_DOCUMENTS),
                    note.getCreateTime() + ":" + note.getTime()
                            + ":" + newName.replaceAll("/", StringUtils.REPLACERELE));
            boolean renameTo = oldFile.renameTo(newFile);

            if(renameTo){
                SaveDrawingTask saveDrawingTask = new SaveDrawingTask(this);
                SaveDrawingTask.name = newFile.getName();
                saveDrawingTask.setValue(getEditData());
                new Thread(saveDrawingTask).start();
            }
        }
    }

    /**
     * 调用图库选择
     */
    private void callGallery() {
        HiLog.info(LABEL, " 图片");
        Matisse.from(this)
                .choose(MimeType.of(MimeType.JPEG, MimeType.PNG, MimeType.GIF))
                .countable(true)
                .maxSelectable(INT_3)
                .gridExpectedSize(INT_360)
                .restrictOrientation(AbilityInfo.DisplayOrientation.UNSPECIFIED)
                .thumbnailScale(FLOAT)
                .theme(0)
                .capture(true)
                .forResult(REQUEST_CODE_CHOOSE);
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        super.onAbilityResult(requestCode, resultCode, resultData);

        if (resultCode == RESULT_OK) {
            if (resultData != null) {
                if (requestCode == 1) {
                    HiLog.info(LABEL, "");
                } else if (requestCode == REQUEST_CODE_CHOOSE) {
                    insertImagesSync(resultData);
                }
            }
        }
    }

    private void insertImagesSync(Intent data) {
        insertDialog = new ToastDialog(this);
        insertDialog.setText("正在插入图片...");
        insertDialog.setSwipeToDismiss(false);
        insertDialog.show();

        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NotNull ObservableEmitter<String> emitter) throws Exception {
                List<Uri> mSelected = Matisse.obtainResult(data);
                for (Uri imageUri : mSelected) {
                    String imagePath = SDCardUtil.getFilePathFromUri(NewAbilitySlice.this, imageUri);

                    emitter.onNext(imagePath);
                }
                emitter.onNext("http://b.zol-img.com.cn/sjbizhi/images/10/640x1136/1572123845476.jpg");
                emitter.onNext("https://img.ivsky.com/img/tupian/pre/201903/24/richu_riluo-013.jpg");

                emitter.onComplete();
            }
        })
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onComplete() {
                        if (insertDialog != null && insertDialog.isShowing()) {
                            insertDialog.destroy();
                        }
                        showToast("图片插入成功");
                    }

                    @Override
                    public void onError(Throwable e) {
                        if (insertDialog != null && insertDialog.isShowing()) {
                            insertDialog.destroy();
                        }
                        showToast("图片插入失败:" + e.getMessage());
                    }

                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(String imagePath) {
                        etnewcontent.insertImage(imagePath);
                    }
                });
    }

    private void showToast(String s) {
        getUITaskDispatcher().syncDispatch(new Runnable() {
            @Override
            public void run() {
                MyToast.show(getContext(), s, MyToast.ToastLayout.BOTTOM);
            }
        });
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}